Shader "Unlit/Shadow"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" "LightMode"="UniversalForward" }
        LOD 100

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 4.0
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float3 normalOS : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct Varings
            {
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
                float3 normalWS : TEXCOORD2;
                float3 viewDirWS : TEXCOORD3;
                float4 IVGIColor : TEXCOORD4;
            };


            #pragma multi_compile _ _USE_IVGI _USE_IVGI_2D _USE_IVGI_VERTEX
            
            TEXTURE3D(_MainTex);
            SAMPLER(sampler_MainTex);
            float4 _MainTex_ST;
            int _VolumeSize;
            float3 _VolumeOrigin;
            
            TEXTURE3D(_IVGI_ShadowMap);
            SAMPLER(sampler_IVGI_ShadowMap);
            
            Varings vert (Attributes IN)
            {
                Varings OUT;
                
                VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);
                VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS.xyz);
                OUT.positionCS = TransformObjectToHClip(IN.positionOS);
                OUT.positionCS = positionInputs.positionCS;
                OUT.positionWS =  positionInputs.positionWS; 
                OUT.viewDirWS = GetCameraPositionWS() - positionInputs.positionWS;
                OUT.normalWS = normalInputs.normalWS;
                OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);
                
                return OUT;
            }
            
            float4 frag (Varings IN) : SV_Target
            {
                float shadow = 1;
                #if defined _USE_IVGI
                float3 localPos = (IN.positionWS - _VolumeOrigin) + normalize(IN.normalWS);
                float3 safeSize = float3(_VolumeSize, _VolumeSize, _VolumeSize) - 1.001;
                
                // 判断是否在合法范围
                bool isInside = all(localPos >= float3(0, 0, 0)) && all(localPos <= (safeSize));
                
                if (!isInside)
                {
                    return float4(1, 1, 1, 1);
                }
                
                float3 uvw = localPos / safeSize;
                shadow = SAMPLE_TEXTURE3D_LOD(_IVGI_ShadowMap, sampler_IVGI_ShadowMap, uvw, 0).a;
                
                #else
                //
                float4 shadowCoord = mul(_MainLightWorldToShadow[0], float4(IN.positionWS, 1.0));
                //float shadow = MainLightRealtimeShadow(shadowCoord);
                ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
                half4 shadowParams = GetMainLightShadowParams();
                shadow = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, false);
                
                #endif
            

                return float4(shadow, shadow, shadow, 1); // 可视化阴影
            }
            ENDHLSL
        }

        

        Pass
        {
            Name "ShadowCaster"
            Tags
            {
                "LightMode" = "ShadowCaster"
            }

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ZTest LEqual
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _ALPHATEST_ON
            #pragma shader_feature_local_fragment _GLOSSINESS_FROM_BASE_ALPHA

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
            #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW

            // -------------------------------------
            // Includes
            #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
            ENDHLSL
        }
    }
}
